package com.qf.stream;/*
*王浩政 
*whz
2022/9/6
14:01
*小米商城
*/

import com.qf.pojo.Item;
import com.qf.pojo.Order;
import com.qf.pojo.User;

import java.util.ArrayList;
import java.util.List;
import java.util.function.BinaryOperator;
import java.util.stream.Collectors;

/*
* 内部迭代的方式
* 外部迭代，迭代器，fro循环
* */
public class StreamTest {
    public static void main(String[] args) {
        //模拟得到的一些数据
        ArrayList<User>list=new ArrayList<>();
        for(int i=0;i<10;i++){
            User user=new User();
            user.setName("沙和尚"+i);
            user.setAge(15+i);
            user.setAddress("流沙河");
            list.add(user);
        }
//        ArrayList<User>list2=new ArrayList<>();
//        for (User user : list) {
//            int age=user.getAge();
//            if(age>=19){
//                list2.add(user);
//            }
//
//        }

        //stream的核心思想，每次的原始数据我们不会进行修改，我们修改的都是一个新的数据的副本
//        List<User> user2 = list.stream()
//                //过滤，需要我们传递一个断言对象进去，我们自己进行判断
//                .filter((user -> user.getAge() >= 18))
//                //收集最近的一个stream的结果
//                .collect(Collectors.toList());
       // System.err.println(user2);
   //     System.out.println(user2);
        //map转换，从一个数据类型编程另外一个数据类型（可以还是当前的数据类型）。利用我们内部迭代到的对象进行操作得到一个新的结果，然后返回
        //我想把所有用户的名字取出来放到一个几个
//        ArrayList<String>list3=new ArrayList<>();
//        for (User user : list) {
//            String name = user.getName();
//            list3.add(name);
//        }
//         List<String> names = list.stream()
//                //.map(user->user.getName())
//                .map(User::getName)
//                .collect(Collectors.toList());
//        System.out.println(names);
        ArrayList<String> nameSource = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            nameSource.add("诺克萨斯自助台"+i);
        }
        //我像遍历上面的字符串，用每一个字符串作为User的name属性，创建User对象，然后将User对象保存到集合中。
//        List<User> allUsers = new ArrayList<>();
//        for (String name : nameSource) {
//            User user=new User();
//            user.setName(name);
//            allUsers.add(user);
//        }


//        List<User> userList1 = nameSource.stream().map((name) -> {
//            User user = new User();
//            user.setName(name);
//            return user;
//        }).collect(Collectors.toList());
//        System.out.println(userList1);

//        list.forEach(System.err::println);
//        list.stream().forEach(System.err::println);


//        List<User> userList2 = list.stream()
//                //peek和foreach是一样的，不同的是peek不会结束stream peek的作用就是让你再中间的·时候完成一次遍历
//                .peek(System.err::println)
//                .filter((user -> user.getAge() > 17))
//                .collect(Collectors.toList());
//        System.out.println(userList2);


//        List<User> userList3 = list.stream()
//                //peek和foreach是一样的，不同的是peek不会结束stream peek的作用就是让你再中间的·时候完成一次遍历
//                //.peek(user -> user.setName(user.getName()+"--->peek"))
//                .map(user -> {
//                    user.setName(user.getName()+"---->map");
//                    return user;
//                })
//                .filter((user -> user.getAge() > 17))
//                .collect(Collectors.toList());
//        System.out.println(userList3);



//        boolean allMatch = list.stream()
//                //allmatch 所有的数据都需要符合要求，一个不行，就要报错
//                .allMatch(user -> user.getAge() > 15);
//        System.out.println(allMatch);
//
//        System.out.println(list.stream()
//                //所有的数据只要有一个符合断言就是true
//                .anyMatch(user -> user.getAge() > 10));

        //求数量
     //   System.out.println(list.stream().filter(user -> user.getAge() > 10).count());


        //peek跟forEach的区别，peek不会结束，所以我们需要手动的来去结束


//        list.stream()
//                .distinct()
//              //  .peek(System.err::println).count();
//        .peek(System.err::println).distinct().findAny();


//        System.out.println(list.stream()
//                //去重，会根据数据的hashcode和equals来进行判断，相同的hashcode和返回true的equals代表相同的对象。
//                .distinct()
//                .peek(System.err::println)
//                .count()
//        );

        List<Order>orderList=new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Order order=new Order();
            order.setId(i);
        List<Item>items=new ArrayList<>();
            for (int i1 = 0; i1 < 5; i1++) {
                Item item = new Item();
                item.setName("鼠标==>"+i+"--->"+i1);
                item.setPrice(i1+2);
                items.add(item);
            }
            order.setItems(items);
            orderList.add(order);
        }
//        List<Item>itemList=new ArrayList<>();
//        for (Order order : orderList) {
//            List<Item>items=order.getItems();
//            itemList.addAll(items);
//        }
       // List<List<Item>> collect = orderList.stream().map(Order::getItems).collect(Collectors.toList());


//        List<Item> itemList = orderList.stream()
//                //我们如果有一个集合，集合中的每个数据内部还有一个集合，我们想把所有集合的数据保存到一个集合中，可以使用flatMap，这只是一个试用的场景
//                .flatMap(order -> order.getItems().stream())
//                .collect(Collectors.toList());
//        System.out.println(itemList.size());
        //可以用来模拟分页
        //System.out.println(orderList.stream().
        //跳过几个数据
        // skip(3)
        // .limit(2)
        // .collect(Collectors.toList()));
//        System.out.println(orderList.stream()
//                //跳过几个数据
//                .skip(2)
//                //只保留几个数据
//                .limit(2).count());

        //求最小值，需要我们自己重写一个比较函数，求返回顺序
       // System.out.println(orderList.stream().min((obj2, obj1) -> obj1.getId() - obj2.getId()).get());

//        orderList.stream().reduce(new BinaryOperator<Order>() {
//            @Override
//            public Order apply(Order order, Order order2) {
//                return null;
//            }
//        })
        //遍历数据，第一次传递前两个数据进来。要求我们反悔哦一个数据，返回的数据也会作为下一次的第一个数据
//        Order order = orderList.stream().reduce((order1, order2) -> {
//            System.out.println("第一个"+order1);
//            System.out.println("第二个"+order2);
//            //return order1;//这里返回什么数据，下次就作为第一个数据，可以返回新创建的数据，不一定非得从传递过来的参数中取
//            return order1;
//        }).get();
//        System.out.println(order);

       // orderList.stream().parallel()//转成异步，也就是多个线程同时进行
//        orderList.parallelStream()//获取异步的stream
//        .sequential()//转成同步

    }
}
